package com.huatai.saas.controller;

import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.huatai.common.api.R;
import com.huatai.common.config.MinioAPI;
import com.huatai.common.constant.MinioCommonBucket;
import com.huatai.common.controller.BaseController;
import com.huatai.common.error.exception.ServiceException;
import com.huatai.saas.constant.MinioBucket;
import com.huatai.saas.dto.BaseDto;
import com.huatai.saas.dto.ClientVersionInfoDto;
import com.huatai.saas.dto.UpdateClientVersionDto;
import com.huatai.saas.service.ClientVersionService;
import io.swagger.annotations.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

/**
 * @program: nanming-saas
 * @author: zcw
 * @create: 2024-04-17
 * @description: 客户端版本的控制器
 */
@RestController
@Slf4j
@RequestMapping("/client")
@Api(value = "客户端软件管理", tags = "客户端软件管理")
public class ClientVersionController extends BaseController {

	@Autowired
	private ClientVersionService clientVersionService;

	@Autowired
	private MinioAPI minioAPI;


	@GetMapping("/list-version")
	@ApiOperation(value = "客户端版本列表", notes = "客户端版本列表")
	@ApiOperationSupport(order = 1)
	public R listClientVersion(BaseDto baseDto) {
		return R.data(clientVersionService.listClientVersion(baseDto));
	}

	@PostMapping("/upload")
	@ApiOperation(value = "客户端版本上传", notes = "客户端版本上传")
	@ApiOperationSupport(order = 2)
	public R uploadClient(@ApiParam(name = "client", value = "客户端软件压缩包", required = true) MultipartFile client) {
		try {
			//规定日期格式
			DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
			//获取上传时的当前时间
			LocalDateTime now = LocalDateTime.now();
			//将当前时间按照规定格式转换
			String format = now.format(formatter);
			// 获取源文件名
			String orgName = client.getOriginalFilename();
			// 获取后缀
			String suffix = orgName.substring(orgName.lastIndexOf("."));
			//给要上传的文件起名字
			String fileName = format + "/" + System.currentTimeMillis() + suffix;
			//将文件上传到minio中存储，并将文件路径返回
			minioAPI.uploadInputStream(MinioCommonBucket.HUATAI_PUB_BUCKET_URL, fileName, client.getInputStream(), client.getContentType());
			return R.data(fileName);
		} catch (Exception e) {
			return R.fail("客户端上传失败");
		}
	}

	@PostMapping("/fileupload")
	@ApiOperation(value = "公共文件上传", notes = "公共文件上传")
	@ApiOperationSupport(order = 2)
	public R fileUpload(@ApiParam(name = "file", value = "文件", required = true) MultipartFile file) {
		try {
			//规定日期格式
			DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
			//获取上传时的当前时间
			LocalDateTime now = LocalDateTime.now();
			//将当前时间按照规定格式转换
			String format = now.format(formatter);
			// 获取源文件名
			String orgName = file.getOriginalFilename();
			// 获取后缀
			String suffix = orgName.substring(orgName.lastIndexOf("."));
			//给要上传的文件起名字
			String fileName = format + "/" + System.currentTimeMillis() + suffix;
			//将文件上传到minio中存储，并将文件路径返回
			minioAPI.uploadInputStream(MinioCommonBucket.HUATAI_PUB_BUCKET_URL, fileName, file.getInputStream(), file.getContentType());
			return R.data(minioAPI.getCOMINFO() + "/" + MinioCommonBucket.HUATAI_PUB_BUCKET_URL + "/" + fileName);
		} catch (Exception e) {
			return R.fail("文件上传失败");
		}
	}

	@PostMapping("/save")
	@ApiOperation(value = "保存上传的客户端版本信息", notes = "保存上传的客户端版本信息")
	@ApiOperationSupport(order = 3)
	public R savaClientVersionInfo(@RequestBody ClientVersionInfoDto clientInfo) {
		return R.data(clientVersionService.uploadClient(clientInfo));
	}

	@GetMapping("/download")
	@ApiOperation(value = "客户端下载", notes = "客户端下载")
	@ApiOperationSupport(order = 4)
	public void downloadClient(@ApiParam(name = "versionNumber", value = "版本号", required = true) @RequestParam String versionNumber, HttpServletResponse response) {
		try {
			// 根据版本号获取下载链接
			String url = clientVersionService.getUrl(versionNumber);
			// 获取文件对象
			InputStream object = minioAPI.download(MinioCommonBucket.HUATAI_PUB_BUCKET_URL, url);
			// 创建一个字节数组
			byte[] bytes = new byte[1024];
			int len = 0;
			// 清除响应头中的信息
			response.reset();
			// 设置响应头类型
			response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(url.substring(url.lastIndexOf("/") + 1), "UTF-8"));
			// 设置响应正文类型
			response.setContentType("application/octet-stream");
			// 设置编码
			response.setCharacterEncoding("UTF-8");
			// 获取网络输出流对象
			OutputStream outputStream = response.getOutputStream();
			// 输出文件
			while ((len = object.read(bytes)) > 0) {
				outputStream.write(bytes, 0, len);
			}
			// 关闭输出流
			outputStream.close();
		} catch (Exception ex) {
			ex.printStackTrace();
			response.setHeader("Content-type", "text/html;charset=UTF-8");
			String message = "客户端下载失败!";
			OutputStream os = null;
			try {
				os = response.getOutputStream();
				os.write(message.getBytes("UTF-8"));
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	@GetMapping("/downloadOne")
	@ApiOperation(value = "客户端下载(单次)", notes = "客户端下载(单次)")
	@ApiOperationSupport(order = 4)
	public void downloadOne(@ApiParam(name = "versionNumber", value = "版本号", required = true) @RequestParam String versionNumber, HttpServletResponse response) {
		try {
			// 根据版本号获取下载链接
			String url = clientVersionService.getUrl(versionNumber);
			// 获取文件对象
			InputStream object = minioAPI.download(MinioCommonBucket.HUATAI_PUB_BUCKET_URL, url);
			// 创建一个字节数组
			byte[] bytes = new byte[1024 * 10];
			int read;
			// 清除响应头中的信息
			response.reset();
			// 设置响应头类型
			response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(url.substring(url.lastIndexOf("/") + 1), "UTF-8"));
			// 设置响应正文类型
			response.setContentType("application/octet-stream");
			// 设置编码
			response.setCharacterEncoding("UTF-8");
			// 获取网络输出流对象
			OutputStream outputStream = response.getOutputStream();
			// 输出文件
			do {
				read = object.read(bytes);
				outputStream.write(bytes, 0, read);
			} while (-1 != read);
//			while ((len = object.read(bytes)) > 0) {
//				outputStream.write(bytes, 0 , len);
//			}
			// 关闭输出流
			outputStream.close();
			object.close();
		} catch (Exception ex) {
			ex.printStackTrace();
			response.setHeader("Content-type", "text/html;charset=UTF-8");
			String message = "客户端下载失败!";
			OutputStream os = null;
			try {
				os = response.getOutputStream();
				os.write(message.getBytes("UTF-8"));
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	@GetMapping("/filedownload")
	@ApiOperation(value = "文件下载", notes = "文件下载")
	@ApiOperationSupport(order = 4)
	public R<String> fileDownload(@ApiParam(name = "versionNumber", value = "版本号", required = true) @RequestParam String versionNumber, HttpServletResponse response) {
		String url = minioAPI.getCOMINFO() + "/" + MinioCommonBucket.HUATAI_PUB_BUCKET_URL + "/" + clientVersionService.getUrl(versionNumber);
		return R.data(url);
	}

	@PostMapping("/del/{id}")
	@ApiOperation(value = "客户端版本删除", notes = "客户端版本删除")
	@ApiOperationSupport(order = 5)
	@ApiImplicitParam(name = "id", value = "客户端版本id", required = true)
	public R delClientVersion(@PathVariable Long id) {
		return R.data(clientVersionService.delClientVersion(id));
	}

	@PostMapping("/update")
	@ApiOperation(value = "修改客户端软件信息", notes = "修改客户端软件信息")
	@ApiOperationSupport(order = 6)
	public R updateClientVersionInfo(@RequestBody UpdateClientVersionDto updateClientVersionDto) {
		return R.data(clientVersionService.updateClientVersionInfo(updateClientVersionDto));
	}

}
